package cn.bupt.adt.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.fasterxml.jackson.databind.ObjectMapper;

import cn.bupt.adt.constant.Constants;
import cn.bupt.adt.dao.autogenerate.InstitutionAppUserMapper;
import cn.bupt.adt.dao.autogenerate.InstitutionMapper;
import cn.bupt.adt.dao.autogenerate.InstitutionViewMapper;
import cn.bupt.adt.dao.autogenerate.OrderViewMapper;
import cn.bupt.adt.entity.autogenerate.Institution;
import cn.bupt.adt.entity.autogenerate.InstitutionAppUser;
import cn.bupt.adt.entity.autogenerate.InstitutionAppUserExample;
import cn.bupt.adt.entity.autogenerate.InstitutionExample;
import cn.bupt.adt.entity.autogenerate.InstitutionView;
import cn.bupt.adt.entity.autogenerate.InstitutionViewExample;
import cn.bupt.adt.entity.autogenerate.OrderView;
import cn.bupt.adt.entity.autogenerate.OrderViewExample;
import cn.bupt.adt.model.InstitutionModel;
import cn.bupt.adt.service.IInstitutionService;
import cn.bupt.adt.service.IOrderService;
import cn.bupt.adt.util.AccountUtil;
import cn.bupt.adt.util.BeanUtil;
import cn.bupt.adt.util.ImageUtil;
import cn.bupt.adt.util.MD5Util;
import cn.bupt.adt.util.SendSMSUtil;
@Service
public class InstitutionService implements IInstitutionService {

	@Autowired
	InstitutionMapper institutionMapper;
	
	@Autowired
	IOrderService orderService;
	
	@Autowired
	InstitutionAppUserMapper institutionAppUserMapper;
	
	@Autowired
	OrderViewMapper orderViewMapper;
	
	@Autowired
	InstitutionViewMapper institutionViewMapper;
	public boolean addInstitution(Institution ins,HttpServletRequest request) {
		MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
		String rootPath = req.getSession().getServletContext().getRealPath("")+"/../"+Constants.IMAGE_PATH;
		List<MultipartFile> appears = req.getFiles("appears");
		List<MultipartFile> certs = req.getFiles("certs");
		List<MultipartFile> devs = req.getFiles("devs");
		MultipartFile portrait = req.getFile("portr");
		Long time = System.currentTimeMillis();
		String timePath = time.toString()+"/";
		List<String> path = new ArrayList<>();
		try {
			path.add(ImageUtil.uploadImage(portrait, Constants.INS_PORTRAIT+timePath, rootPath,1));
			ObjectMapper mapper = new ObjectMapper();
			ins.setPortrait(path.get(0));
			path.clear();
			int i = 0;
			for(MultipartFile appearFile:appears) {
				path.add(ImageUtil.uploadImage(appearFile, Constants.APPEAR_PATH+timePath, rootPath,i));
				i++;
			}
			ins.setAppearanceImg(mapper.writeValueAsString(path));
			path.clear();
			i = 0;
			for(MultipartFile certFile:certs) {
				path.add(ImageUtil.uploadImage(certFile, Constants.INSCERT_PATH+timePath, rootPath,i));
				i++;
			}
			ins.setCertificationImg(mapper.writeValueAsString(path));
			path.clear();
			i = 0;
			for(MultipartFile devFile:devs) {
				path.add( ImageUtil.uploadImage(devFile, Constants.DEV_PATH+timePath, rootPath,i));
				i++;
			}
			ins.setDevicesImg(mapper.writeValueAsString(path));
		}
		catch(Exception e){
			
		}
		//新增的机构的联系电话不能与已有机构的电话相同
		List<Institution> institutions = institutionMapper.selectByExample(new InstitutionExample());
		for(Institution in:institutions)
			if(ins.getPhone().equals(in.getPhone()))
				return false;
		//向机构表插入
		int i = institutionMapper.insert(ins);
		
		//为机构生成账号与密码，账号不能与已有机构的账号相同
		InstitutionAppUser appUser = new InstitutionAppUser();
		List<InstitutionAppUser> appUsers = institutionAppUserMapper.selectByExample(new InstitutionAppUserExample());
		Set<String> accounts = new HashSet<>();
		for(InstitutionAppUser u:appUsers)
			accounts.add(u.getAccount());
		appUser.setAccount(generateAccount(accounts,Constants.ACCOUNT_LENGTH));
		String passwd = generatePasswd(Constants.PASSWD_LENGTH);
		appUser.setPasswd(MD5Util.MD5(passwd));
		appUser.setMoney(0.0);
		appUser.setWaitedToBeWithdrawnMoney(0.0);
		appUser.setInstitutionId(ins.getId());
		appUser.setFinishedOrderNum(0);
		appUser.setFinishOrderMoney(0.0);
		appUser.setPublishOrderNum(0);
		//向客户端机构表插入
		int j = institutionAppUserMapper.insert(appUser);
		//给机构发送短信，告知账号密码
		SendSMSUtil sendSms = new SendSMSUtil();
		sendSms.SendSMS(ins.getPhone(), new String[]{appUser.getAccount(),passwd}, Constants.SMS_JIGOUZHUCE);
		return i == 1 && j == 1;
	}
	private String generateAccount(Set<String> accounts,int len) {
		String res = null;
		do {
			res = AccountUtil.getRandomAccount(len);
		}while(accounts.contains(res));
		return res;
	}
	private String generatePasswd(int len) {
		return AccountUtil.getRandomAccount(len);
	}
	public boolean modifyInstitution(Institution ins) {
		List<InstitutionModel> allInstitutions = getAllInstitutions();
		for(InstitutionModel im:allInstitutions)
			if(im.getPhone().equals(ins.getPhone()))
				return false;
		return institutionMapper.updateByPrimaryKeySelective(ins) == 1;
	}

	public boolean removeInstitution(Institution ins) {
		// TODO Auto-generated method stub
		return false;
	}

	public List<InstitutionModel> getAllInstitutions() {
		List<InstitutionView> lists= institutionViewMapper.selectByExample(new InstitutionViewExample());
		List<InstitutionModel> res = new ArrayList<InstitutionModel>(lists.size());
		Set<String> labels = null;
		StringBuilder sb = new StringBuilder();
		for(InstitutionView ins:lists){
			InstitutionModel im = new InstitutionModel();
			try {
				BeanUtil.fatherToChild(ins, im);
			} catch (Exception e) {
				e.printStackTrace();
			}
			labels = getOperationTypesByInstitutionAppUserId(ins.getId());
			im.setCerts(ImageUtil.convertToList(ins.getCertificationImg()));
			im.setAppears(ImageUtil.convertToList(ins.getAppearanceImg()));
			im.setDevs(ImageUtil.convertToList(ins.getDevicesImg()));
			int i = 0;
			for(String s:labels) {
				if(i++ < 3) {
					sb.append(s);
					sb.append(',');
				}
				else
					break;
			}
			if(sb.length() == 0)
				im.setLabels("");
			else
				im.setLabels(sb.substring(0, sb.length()-1));
			sb.delete(0, sb.length());
			res.add(im);
		}
		return res;
	}
	private Set<String> getOperationTypesByInstitutionId(int id){
		InstitutionAppUserExample ex = new InstitutionAppUserExample();
		ex.createCriteria().andInstitutionIdEqualTo(id);
		InstitutionAppUser appuser = institutionAppUserMapper.selectByExample(ex).get(0);
		return getOperationTypesByInstitutionAppUserId(appuser.getId());
	}
	private Set<String> getOperationTypesByInstitutionAppUserId(int id){
		OrderViewExample ex = new OrderViewExample();
		ex.createCriteria().andInstitutionIdEqualTo(id);
		List<OrderView> list = orderViewMapper.selectByExampleWithBLOBs(ex);
		System.out.println("ordersize:"+list.size());
		Set<String> names = new HashSet<String>();
		for(OrderView or:list)
			names.add(or.getSubOperationTypeName());
		return names;
	}
	@Override
	public boolean deleteInstitutionById(int id) {
		return institutionMapper.deleteByPrimaryKey(id) == 1;
	}
	@Override
	public InstitutionModel getInstitutionById(int id) {
		InstitutionViewExample ex = new InstitutionViewExample();
		ex.createCriteria().andInstitutionIdEqualTo(id);
		InstitutionView ins = institutionViewMapper.selectByExample(ex).get(0);
		InstitutionModel im = new InstitutionModel();
		try {
			BeanUtil.fatherToChild(ins, im);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Set<String> labels = getOperationTypesByInstitutionAppUserId(ins.getId());
		StringBuilder sb = new StringBuilder();
		im.setCerts(ImageUtil.convertToList(ins.getCertificationImg()));
		im.setAppears(ImageUtil.convertToList(ins.getAppearanceImg()));
		im.setDevs(ImageUtil.convertToList(ins.getDevicesImg()));
		for(String s:labels) {
			sb.append(s);
			sb.append(',');
		}
		if(sb.length() == 0)
			im.setLabels("");
		else
			im.setLabels(sb.substring(0, sb.length()-1));
		return im;
	}
	@Override
	public InstitutionModel getInstitutionByAppId(int id) {
		InstitutionViewExample ex = new InstitutionViewExample();
		ex.createCriteria().andIdEqualTo(id);
		InstitutionView ins = institutionViewMapper.selectByExample(ex).get(0);
		InstitutionModel im = new InstitutionModel();
		try {
			BeanUtil.fatherToChild(ins, im);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Set<String> labels = getOperationTypesByInstitutionAppUserId(ins.getId());
		StringBuilder sb = new StringBuilder();
		im.setCerts(ImageUtil.convertToList(ins.getCertificationImg()));
		im.setAppears(ImageUtil.convertToList(ins.getAppearanceImg()));
		im.setDevs(ImageUtil.convertToList(ins.getDevicesImg()));
		for(String s:labels) {
			sb.append(s);
			sb.append(',');
		}
		if(sb.length() == 0)
			im.setLabels("");
		else
			im.setLabels(sb.substring(0, sb.length()-1));
		return im;
	}
	@Override
	public boolean modifyInstitution(Institution ins, HttpServletRequest request) {
		MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
		String rootPath = req.getSession().getServletContext().getRealPath("")+"/../"+Constants.IMAGE_PATH;
		List<MultipartFile> appears = req.getFiles("appear");
		List<MultipartFile> certs = req.getFiles("certi");
		List<MultipartFile> devs = req.getFiles("devi");
		MultipartFile portrait = req.getFile("portr");
		Long time = System.currentTimeMillis();
		String timePath = time.toString()+"/";
		List<String> path = new ArrayList<>();
		try {
			ObjectMapper mapper = new ObjectMapper();
			if(portrait != null && portrait.getSize() != 0) {
				path.add(ImageUtil.uploadImage(portrait, Constants.INS_PORTRAIT+timePath, rootPath,1));
				ins.setPortrait(path.get(0));
				path.clear();
			}
			int i = 0;
			if(appears.size() != 0 && appears.get(0).getSize() != 0) {
				for(MultipartFile appearFile:appears) {
					path.add(ImageUtil.uploadImage(appearFile, Constants.APPEAR_PATH+timePath, rootPath,i));
					i++;
				}
				ins.setAppearanceImg(mapper.writeValueAsString(path));
				path.clear();
			}
			if(certs.size() != 0 && certs.get(0).getSize() != 0) {
				i = 0;
				for(MultipartFile certFile:certs) {
					path.add(ImageUtil.uploadImage(certFile, Constants.INSCERT_PATH+timePath, rootPath,i));
					i++;
				}
				ins.setCertificationImg(mapper.writeValueAsString(path));
				path.clear();
			}
			if(devs.size() != 0 && devs.get(0).getSize() != 0) {
				i = 0;
				for(MultipartFile devFile:devs) {
					path.add( ImageUtil.uploadImage(devFile, Constants.DEV_PATH+timePath, rootPath,i));
					i++;
				}
				ins.setDevicesImg(mapper.writeValueAsString(path));
			}
		}
		catch(Exception e){
			
		}		
		return institutionMapper.updateByPrimaryKeySelective(ins) == 1;
	}
	private List<InstitutionModel> transferModel(List<InstitutionView> lists) {
		List<InstitutionModel> res = new ArrayList<InstitutionModel>(lists.size());
		Set<String> labels = null;
		StringBuilder sb = new StringBuilder();
		for(InstitutionView ins:lists){
			InstitutionModel im = new InstitutionModel();
			try {
				BeanUtil.fatherToChild(ins, im);
			} catch (Exception e) {
				e.printStackTrace();
			}
			labels = getOperationTypesByInstitutionAppUserId(ins.getId());
			im.setCerts(ImageUtil.convertToList(ins.getCertificationImg()));
			im.setAppears(ImageUtil.convertToList(ins.getAppearanceImg()));
			im.setDevs(ImageUtil.convertToList(ins.getDevicesImg()));
			int i = 0;
			for(String s:labels) {
				if(i++ < 3) {
					sb.append(s);
					sb.append(',');
				}
				else
					break;
			}
			if(sb.length() == 0)
				im.setLabels("");
			else
				im.setLabels(sb.substring(0, sb.length()-1));
			sb.delete(0, sb.length());
			res.add(im);
		}
		return res;		
	}
	@Override
	public List<InstitutionModel> getInstitutionByFuzzyName(String content) {
		InstitutionViewExample ex = new InstitutionViewExample();
		ex.createCriteria().andNameLike('%'+content+'%');
		List<InstitutionView> lists= institutionViewMapper.selectByExample(ex);
		return transferModel(lists);
	}
	@Override
	public List<InstitutionModel> getInstitutionByPhone(String content) {
		InstitutionViewExample ex = new InstitutionViewExample();
		ex.createCriteria().andPhoneEqualTo(content);
		List<InstitutionView> lists= institutionViewMapper.selectByExample(ex);
		return transferModel(lists);
	}
	
	@Override
	public String getInstitutionNameById(Integer id) {
		InstitutionViewExample ex = new InstitutionViewExample();
		ex.createCriteria().andIdEqualTo(id);return institutionViewMapper.selectByExample(ex).get(0).getName();
	}


}
